package nina.yiyou.performance.s20confirm.output


import nina.yiyou.salary.output.util.CsvLineMaker
import nina.yiyou.salary.output.util.KeySheetReader
import nina.yiyou.salary.output.util.OutCsvWriter
import org.apache.poi.ss.usermodel.Sheet

import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.StandardCopyOption

class PerformConfirmGenerator {

  PerformConfirmGenerator(Path templatePath, List<Map> employeeResults, Path outDir, Path tmpDir) {
    _templatePath = templatePath
    _employeeResults = employeeResults
    _outDir = outDir
    _tmpDir = tmpDir
  }

  void generate() {
    def keyReader = { Sheet s -> new KeySheetReader(s).readKeys() }
    def resultKeys = new PerformGeneratePreparer<List<String>>(_templatePath, keyReader, _outDir, _tmpDir).prepare()

    _employeeResults.each { writeEmployeeFiles(it, resultKeys) }
    writeListCsv()
  }

  private void writeEmployeeFiles(Map result, List<String> resultKeys) {
    EmployeePath path = getPath(result)

    Files.copy(_templatePath, path.excel(), StandardCopyOption.REPLACE_EXISTING)
    writeDataCsv(resultKeys, result, path.data())
  }

  private void writeDataCsv(List<String> keys, Map<String, ?> result, Path outPath) {
    new OutCsvWriter(outPath, keys
        .collect { result[it] }
        .collect { new CsvLineMaker([it]).make() }).write()
  }

  private void writeListCsv() {
    List<String> lines = _employeeResults
        .collect { getPath(it) }
        .collect { new CsvLineMaker([it.excel(), it.data()]).make() }

    new OutCsvWriter(_tmpDir.resolve('0.csv'), lines).write()
  }

  private EmployeePath getPath(Map result) {
    def path = { String key -> result['计算.路径.' + key] as Path }
    return new EmployeePath() {
      @Override
      Path excel() { return path.call('excel') }

      @Override
      Path data() { return path.call('data') }
    }
  }

  interface EmployeePath {

    Path excel()

    Path data()
  }

  private final Path _templatePath
  private final List<Map> _employeeResults

  private final Path _outDir
  private final Path _tmpDir
}
